const fs = require("fs")
const path = require("path")
const Koa = require("koa")
const serve = require("koa-static")
const { createBundleRenderer } = require("vue-server-renderer")
const LRU = require("lru-cache")
const cache = new LRU({
  max: 500,
  maxAge: 1000 * 60 * 60
});

const resolve = (file) => path.resolve(__dirname, file)
const app = new Koa()
const template = fs.readFileSync(resolve("./src/index.template.html"), "utf-8")

function createRenderer(bundle, options) {
  return createBundleRenderer(
    bundle,
    Object.assign(options, {
      template,
      cache,
      basedir: resolve("./dist"),
      runInNewContext: false,
    })
  )
}

let renderer
const bundle = require("./dist/vue-ssr-server-bundle.json")
const clientManifest = require("./dist/vue-ssr-client-manifest.json")
renderer = createRenderer(bundle, {
  clientManifest,
})

/**
 * 渲染函数
 * @param ctx
 * @param next
 * @returns {Promise}
 */
function render(ctx, next) {
  ctx.set("Content-Type", "text/html")
  return new Promise(function (resolve, reject) {
    const handleError = (err) => {
      if (err && err.code === 404) {
        ctx.status = 404
        ctx.body = "404 | Page Not Found"
      } else {
        ctx.status = 500
        ctx.body = "500 | Internal Server Error"
        console.error(`error during render : ${ctx.url}`)
        console.error(err.stack)
      }
      resolve()
    }
    const context = {
      title: "Vue Ssr _daes",
      url: ctx.url,
    }
    renderer.renderToString(context, (err, html) => {
      if (err) {
        return handleError(err)
      }
      console.log(html)
      ctx.body = html
      resolve()
    })
  })
}

app.use(serve(__dirname + '/dist'))

app.use(render);

app.listen(8080, "0.0.0.0", () => {
  console.log(`server started at http:127.0.0.1:${8080}`)
})
